// Copyright 2024 - 2025 Crunchy Data Solutions, Inc.
//
// SPDX-License-Identifier: Apache-2.0

package collector

import (
	"context"
	"testing"

	"gotest.tools/v3/assert"

	"github.com/crunchydata/postgres-operator/internal/feature"
	"github.com/crunchydata/postgres-operator/internal/testing/require"
	"github.com/crunchydata/postgres-operator/pkg/apis/postgres-operator.crunchydata.com/v1beta1"
)

func TestNewConfigForPgBackrestRepoHostPod(t *testing.T) {
	t.Run("EmptyInstrumentationSpec", func(t *testing.T) {
		gate := feature.NewGate()
		assert.NilError(t, gate.SetFromMap(map[string]bool{
			feature.OpenTelemetryLogs: true,
		}))
		ctx := feature.NewContext(context.Background(), gate)
		repos := []v1beta1.PGBackRestRepo{
			{
				Name:   "repo1",
				Volume: new(v1beta1.RepoPVC),
			},
		}
		var instrumentation *v1beta1.InstrumentationSpec
		require.UnmarshalInto(t, &instrumentation, `{}`)
		config := NewConfigForPgBackrestRepoHostPod(ctx, instrumentation, repos, "/test/directory")

		result, err := config.ToYAML()
		assert.NilError(t, err)
		assert.DeepEqual(t, result, `# Generated by postgres-operator. DO NOT EDIT.
# Your changes will not be saved.
exporters:
  debug:
    verbosity: detailed
extensions:
  file_storage/pgbackrest_logs:
    create_directory: false
    directory: /test/directory/receiver
    fsync: true
processors:
  batch/1s:
    timeout: 1s
  batch/200ms:
    timeout: 200ms
  batch/logs:
    send_batch_size: 8192
    timeout: 200ms
  groupbyattrs/compact: {}
  resource/pgbackrest:
    attributes:
    - action: insert
      key: k8s.container.name
      value: pgbackrest
    - action: insert
      key: k8s.namespace.name
      value: ${env:K8S_POD_NAMESPACE}
    - action: insert
      key: k8s.pod.name
      value: ${env:K8S_POD_NAME}
    - action: insert
      key: process.executable.name
      value: pgbackrest
  resourcedetection:
    detectors: []
    override: false
    timeout: 30s
  transform/pgbackrest_logs:
    log_statements:
    - statements:
      - set(instrumentation_scope.name, "pgbackrest")
      - set(instrumentation_scope.schema_url, "https://opentelemetry.io/schemas/1.29.0")
      - 'merge_maps(log.cache, ExtractPatterns(log.body, "^(?<timestamp>\\d{4}-\\d{2}-\\d{2}
        \\d{2}:\\d{2}:\\d{2}\\.\\d{3}) (?<process_id>P\\d{2,3})\\s*(?<error_severity>\\S*):
        (?<message>(?s).*)$"), "insert") where Len(log.body) > 0'
      - set(log.severity_text, log.cache["error_severity"]) where IsString(log.cache["error_severity"])
      - set(log.severity_number, SEVERITY_NUMBER_TRACE) where log.severity_text ==
        "TRACE"
      - set(log.severity_number, SEVERITY_NUMBER_DEBUG) where log.severity_text ==
        "DEBUG"
      - set(log.severity_number, SEVERITY_NUMBER_DEBUG2) where log.severity_text ==
        "DETAIL"
      - set(log.severity_number, SEVERITY_NUMBER_INFO) where log.severity_text ==
        "INFO"
      - set(log.severity_number, SEVERITY_NUMBER_WARN) where log.severity_text ==
        "WARN"
      - set(log.severity_number, SEVERITY_NUMBER_ERROR) where log.severity_text ==
        "ERROR"
      - set(log.time, Time(log.cache["timestamp"], "%Y-%m-%d %H:%M:%S.%L")) where
        IsString(log.cache["timestamp"])
      - set(log.attributes["process.pid"], log.cache["process_id"])
      - set(log.attributes["log.record.original"], log.body)
      - set(log.body, log.cache["message"])
receivers:
  filelog/pgbackrest_log:
    include:
    - /test/directory/*.log
    - /test/directory/*.log.1
    multiline:
      line_start_pattern: ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}|^-{19}
    storage: file_storage/pgbackrest_logs
service:
  extensions:
  - file_storage/pgbackrest_logs
  pipelines:
    logs/pgbackrest:
      exporters:
      - debug
      processors:
      - resource/pgbackrest
      - transform/pgbackrest_logs
      - resourcedetection
      - batch/logs
      - groupbyattrs/compact
      receivers:
      - filelog/pgbackrest_log
`)
	})

	t.Run("InstrumentationSpecDefined", func(t *testing.T) {
		gate := feature.NewGate()
		assert.NilError(t, gate.SetFromMap(map[string]bool{
			feature.OpenTelemetryLogs: true,
		}))
		ctx := feature.NewContext(context.Background(), gate)
		repos := []v1beta1.PGBackRestRepo{
			{
				Name:   "repo1",
				Volume: new(v1beta1.RepoPVC),
			},
		}
		config := NewConfigForPgBackrestRepoHostPod(ctx, testInstrumentationSpec(), repos, "/another/directory")

		result, err := config.ToYAML()
		assert.NilError(t, err)
		assert.DeepEqual(t, result, `# Generated by postgres-operator. DO NOT EDIT.
# Your changes will not be saved.
exporters:
  debug:
    verbosity: detailed
  googlecloud:
    log:
      default_log_name: opentelemetry.io/collector-exported-log
    project: google-project-name
extensions:
  file_storage/pgbackrest_logs:
    create_directory: false
    directory: /another/directory/receiver
    fsync: true
processors:
  batch/1s:
    timeout: 1s
  batch/200ms:
    timeout: 200ms
  batch/logs:
    send_batch_size: 8192
    timeout: 200ms
  groupbyattrs/compact: {}
  resource/pgbackrest:
    attributes:
    - action: insert
      key: k8s.container.name
      value: pgbackrest
    - action: insert
      key: k8s.namespace.name
      value: ${env:K8S_POD_NAMESPACE}
    - action: insert
      key: k8s.pod.name
      value: ${env:K8S_POD_NAME}
    - action: insert
      key: process.executable.name
      value: pgbackrest
  resourcedetection:
    detectors: []
    override: false
    timeout: 30s
  transform/pgbackrest_logs:
    log_statements:
    - statements:
      - set(instrumentation_scope.name, "pgbackrest")
      - set(instrumentation_scope.schema_url, "https://opentelemetry.io/schemas/1.29.0")
      - 'merge_maps(log.cache, ExtractPatterns(log.body, "^(?<timestamp>\\d{4}-\\d{2}-\\d{2}
        \\d{2}:\\d{2}:\\d{2}\\.\\d{3}) (?<process_id>P\\d{2,3})\\s*(?<error_severity>\\S*):
        (?<message>(?s).*)$"), "insert") where Len(log.body) > 0'
      - set(log.severity_text, log.cache["error_severity"]) where IsString(log.cache["error_severity"])
      - set(log.severity_number, SEVERITY_NUMBER_TRACE) where log.severity_text ==
        "TRACE"
      - set(log.severity_number, SEVERITY_NUMBER_DEBUG) where log.severity_text ==
        "DEBUG"
      - set(log.severity_number, SEVERITY_NUMBER_DEBUG2) where log.severity_text ==
        "DETAIL"
      - set(log.severity_number, SEVERITY_NUMBER_INFO) where log.severity_text ==
        "INFO"
      - set(log.severity_number, SEVERITY_NUMBER_WARN) where log.severity_text ==
        "WARN"
      - set(log.severity_number, SEVERITY_NUMBER_ERROR) where log.severity_text ==
        "ERROR"
      - set(log.time, Time(log.cache["timestamp"], "%Y-%m-%d %H:%M:%S.%L")) where
        IsString(log.cache["timestamp"])
      - set(log.attributes["process.pid"], log.cache["process_id"])
      - set(log.attributes["log.record.original"], log.body)
      - set(log.body, log.cache["message"])
receivers:
  filelog/pgbackrest_log:
    include:
    - /another/directory/*.log
    - /another/directory/*.log.1
    multiline:
      line_start_pattern: ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}|^-{19}
    storage: file_storage/pgbackrest_logs
service:
  extensions:
  - file_storage/pgbackrest_logs
  pipelines:
    logs/pgbackrest:
      exporters:
      - googlecloud
      processors:
      - resource/pgbackrest
      - transform/pgbackrest_logs
      - resourcedetection
      - batch/logs
      - groupbyattrs/compact
      receivers:
      - filelog/pgbackrest_log
`)
	})
}
